package com.xinghai.system.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinghai.common.core.domain.entity.SysDictData;
import com.xinghai.common.utils.DateUtils;
import com.xinghai.common.utils.StringUtils;
import com.xinghai.system.domain.XhUseVehicleInfo;
import com.xinghai.system.domain.XhUseVehicleInfoDetails;
import com.xinghai.system.domain.XhVehicleInfoApplyRecord;
import com.xinghai.system.domain.XhVehicleOrderInfo;
import com.xinghai.system.domain.dto.DingTalkTodoDTO;
import com.xinghai.system.domain.dto.XhUseVehicleInfoDto;
import com.xinghai.system.domain.vo.XhVehicleInfoQueryVo;
import com.xinghai.system.mapper.DingUserMapper;
import com.xinghai.system.mapper.XhUseVehicleInfoMapper;
import com.xinghai.system.service.*;
import com.xinghai.system.util.BeanMapperUtils;
import com.xinghai.system.util.XHConstant;
import com.xinghai.system.util.XHUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

/**
 * 用车信息Service业务层处理
 * 
 * @author xinghai
 * @date 2024-07-17
 */
@Service
public class XhUseVehicleInfoServiceImpl extends ServiceImpl<XhUseVehicleInfoMapper, XhUseVehicleInfo> implements IXhUseVehicleInfoService
{
    @Autowired
    private XhUseVehicleInfoMapper xhUseVehicleInfoMapper;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Autowired
    private ISysDictDataService sysDictDataService;

    @Autowired
    private DingdingOaService dingdingOaService;

    @Autowired
    private IXhVehicleInfoApplyRecordService xhVehicleInfoApplyRecordService;

    @Autowired
    private IXhVehicleInfoMaterialService xhVehicleInfoMaterialService;

    @Autowired
    private IXhUseVehicleInfoDetailsService xhUseVehicleInfoDetailsService;

    @Value("${material.port}")
    private String PORT;

    @Value("${material.url}")
    private String MATERIAL_URL;

    @Value("${material.isDmain}")
    private Boolean isDomain;

    @Autowired
    private IXhVehicleOrderInfoService xhVehicleOrderInfoService;
    @Autowired
    private DingUserMapper dingUserMapper;

    /**
     * 查询用车信息
     * 
     * @param id 用车信息主键
     * @return 用车信息
     */
    @Override
    public XhUseVehicleInfo getInfo(Long id)
    {
        XhUseVehicleInfo info = xhUseVehicleInfoMapper.getInfo(id);
        if (info.getBeginAddr()!=null && info.getBeginAddr() !="") {
            info.setBeginAddr(parseBeginAddr(info.getBeginAddr()));
        }
        return info;
    }

    /**
     * 查询用车信息详情
     *
     * @param id 用车信息主键
     * @return 用车信息
     */
    @Override
    public XhUseVehicleInfoDto getDetails(Long id)
    {
        XhUseVehicleInfoDto info = xhUseVehicleInfoMapper.getDetails(id);
        if (StringUtils.isNotEmpty(info.getBeginAddr())) {
            info.setBeginAddr(parseBeginAddr(info.getBeginAddr()));
        }
        return info;
    }

    /**
     * 查询用车信息列表
     * 
     * @param xhUseVehicleInfo 用车信息
     * @return 用车信息
     */
    @Override
    public List<XhUseVehicleInfoDto> list(XhVehicleInfoQueryVo xhVehicleInfoQueryVo)
    {
        List<XhUseVehicleInfoDto> list = xhUseVehicleInfoMapper.list(xhVehicleInfoQueryVo);
        list.stream().forEach(item -> {
            //[{北京市,北京市,东城区=1111}, {河北省,唐山市,路北区=111}]
            if (StringUtils.isNotEmpty(item.getBeginAddr())) {
                String beginAddr = parseBeginAddr(item.getBeginAddr());
                item.setBeginAddr(beginAddr);
            }
        });
        return list;
    }

    /**
     * 解析NeedVehicle
     * @return
     */
    public String parseBeginAddr(String data) {
        // 检查字符串是否以'['开始并且以']'结束
        if (data.startsWith("[") && data.endsWith("]")) {
            // 移除字符串开头的 '[' 和结尾的 ']'
            return data.substring(1, data.length() - 1);
        }
        // 如果字符串不满足条件，直接返回原字符串
        return data;
    }

    /**
     * 新增用车信息
     * 
     * @param xhUseVehicleInfo 用车信息
     * @return 结果
     */
    @Override
    public int insert(XhUseVehicleInfo xhUseVehicleInfo)
    {
        xhUseVehicleInfo.setCreateTime(DateUtils.getNowDate());
        return xhUseVehicleInfoMapper.insert(xhUseVehicleInfo);
    }
    /**
     * 批量新增用车信息
     *
     * @param xhUseVehicleInfoList 用车信息
     * @return 结果
     */
    @Override
    public int insertBatch(List<XhUseVehicleInfo> xhUseVehicleInfoList)
    {
        return xhUseVehicleInfoMapper.insertBatch(xhUseVehicleInfoList);
    }
    /**
     * 修改用车信息
     * 
     * @param xhUseVehicleInfo 用车信息
     * @return 结果
     */
    @Override
    public int update(XhUseVehicleInfo xhUseVehicleInfo)
    {
        xhUseVehicleInfo.setUpdateTime(DateUtils.getNowDate());
        return xhUseVehicleInfoMapper.update(xhUseVehicleInfo);
    }

    /**
     * 批量删除用车信息
     * 
     * @param ids 需要删除的用车信息主键
     * @return 结果
     */
    @Override
    public int deleteBatch(Long[] ids)
    {
        return xhUseVehicleInfoMapper.deleteBatch(ids);
    }

    /**
     * 删除用车信息信息
     * 
     * @param id 用车信息主键
     * @return 结果
     */
    @Override
    public int delete(Long id)
    {
        return xhUseVehicleInfoMapper.delete(id);
    }

    /**
     * 导入用车信息信息
     *
     * @param list 用车信息信息集合
     * @return 结果
     */
    @Override
    @Transactional
    public boolean importData(List<XhUseVehicleInfo> list){
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        try {
            XhUseVehicleInfoMapper xhUseVehicleInfoMapper = sqlSession.getMapper(XhUseVehicleInfoMapper.class);
            list.stream().forEach(item -> xhUseVehicleInfoMapper.insert(item));
            // 提交数据
            sqlSession.commit();
            sqlSession.rollback();
        } catch (Exception e) {
            sqlSession.rollback();
            return false;
        } finally {
            sqlSession.close();
        }
        return true;
    }

    @Override
    public XhUseVehicleInfo getOrderVehicleInfo(Long id) throws Exception {
        XhUseVehicleInfo xhUseVehicleInfo = this.getById(id);
        if (xhUseVehicleInfo == null){
            throw new Exception("请选择要查看用车申请");
        }
        return xhUseVehicleInfo;
    }

    @Override
    public void receiveDingMsg(JSONObject msgJsonObject) throws Exception {
        try{
            //提取流程id
            String processInstanceId = msgJsonObject.getString("processInstanceId");
            //提取消息类型
            String type = msgJsonObject.getString("type");
            //节点名称
            String activityName = msgJsonObject.getString("activityName");
            XhUseVehicleInfo xhUseVehicleInfo = xhUseVehicleInfoMapper.getINfoByProcessInstanceId(processInstanceId);
            if (xhUseVehicleInfo != null){
                SysDictData sysDictData = sysDictDataService.selectDictValue(XHConstant.POINT_TYPE,activityName);
                //节点存在 并且 类型时 start
                if (sysDictData != null && XHConstant.DING_MSG_START.equals(type)){
                    //更新节点
                    xhUseVehicleInfo.setPointType(sysDictData.getDictValue());
                    xhUseVehicleInfoMapper.updateById(xhUseVehicleInfo);
                }
                //保存、更新任务记录
                this.saveOrUpdateRecord(msgJsonObject,xhUseVehicleInfo,type,activityName);
                //生成耗材信息
                this.createMaterialUrl(msgJsonObject,xhUseVehicleInfo,type,activityName);
                //退回 物流公司填写车辆信息
                this.pointApplyInfo(xhUseVehicleInfo,type,activityName,msgJsonObject);
            }
        }catch (Exception e){
            log.error(e.getMessage());
            e.printStackTrace();
        }
    }

    @Override
    public List<XhUseVehicleInfoDto> getListByStatus(XhVehicleInfoQueryVo xhVehicleInfoQueryVo, String status) {
        return xhUseVehicleInfoMapper.getListByStatus(xhVehicleInfoQueryVo,status);
    }

    private void pointApplyInfo(XhUseVehicleInfo xhUseVehicleInfo, String type, String activityName, JSONObject msgJsonObject) {
        //type：cancel；activityName:发起人填写装车信息、装车人员填写装车信息
        if (XHConstant.DING_MSG_CANCEL.equals(type)
                && (StringUtils.equals(activityName,sysDictDataService.selectDictLabel(XHConstant.POINT_TYPE, XHConstant.STR_2))
                || StringUtils.equals(activityName,sysDictDataService.selectDictLabel(XHConstant.POINT_TYPE, XHConstant.STR_3)))){
            //修改订单状态 待审批
            XhVehicleOrderInfo xhVehicleOrderInfo = xhVehicleOrderInfoService.lambdaQuery().eq(XhVehicleOrderInfo::getVehicleId,xhUseVehicleInfo.getId()).one();
            if (xhVehicleOrderInfo != null){
                xhVehicleOrderInfo.setStatus(XHConstant.ORDER_STATUS_APPLY);
                xhVehicleOrderInfo.setRemark(msgJsonObject.getString("remark"));
                xhVehicleOrderInfoService.update(xhVehicleOrderInfo);
            }
        }

        //start 节点 activityName:物流公司品质损失审批；物流公司回执上传
        if (XHConstant.DING_MSG_START.equals(type)
                && (StringUtils.equals(activityName,sysDictDataService.selectDictLabel(XHConstant.POINT_TYPE, XHConstant.STR_10))
                || StringUtils.equals(activityName,sysDictDataService.selectDictLabel(XHConstant.POINT_TYPE, XHConstant.STR_14)))){
            //修改订单状态 待审批
            XhVehicleOrderInfo xhVehicleOrderInfo = xhVehicleOrderInfoService.lambdaQuery().eq(XhVehicleOrderInfo::getVehicleId,xhUseVehicleInfo.getId()).one();
            if (xhVehicleOrderInfo != null){
                xhVehicleOrderInfo.setStatus(XHConstant.ORDER_STATUS_APPLY);
                xhVehicleOrderInfoService.update(xhVehicleOrderInfo);
            }
        }
    }

    public void createMaterialUrl(JSONObject msgJsonObject, XhUseVehicleInfo xhUseVehicleInfo, String type, String activityName) throws Exception {
        //当以下节点审批完成：发起人填写装车信息、装车人员填写装车信息 并且 类型是 finish
        if ((StringUtils.equals(activityName,sysDictDataService.selectDictLabel(XHConstant.POINT_TYPE, XHConstant.STR_2))
                || StringUtils.equals(activityName,sysDictDataService.selectDictLabel(XHConstant.POINT_TYPE, XHConstant.STR_3)))
            && XHConstant.DING_MSG_FINISH.equals(type)){
            if (xhVehicleInfoApplyRecordService.lambdaQuery().eq(XhVehicleInfoApplyRecord::getTaskId,msgJsonObject.getString("taskId")).count() > 0) {
                //发送钉钉消息，提醒相关人耗材明细数据
                // 获取IP地址
                String url = isDomain ? MATERIAL_URL : MATERIAL_URL + ":" + PORT;
                String needUrl = StringUtils.format("{}/consumables?vehicleId={}&type=0", url, xhUseVehicleInfo.getId());
                String loadUrl = StringUtils.format("{}/loadConsumables?vehicleId={}&type=1", url, xhUseVehicleInfo.getId());
                try {
                    //创建钉钉待办提醒
                    String staffId = msgJsonObject.getString("staffId");
                    String dingCreateBy = xhUseVehicleInfo.getDingCreateBy();
                    //需求人消息
                    DingTalkTodoDTO dingTalkTodoDTO = new DingTalkTodoDTO();
                    dingTalkTodoDTO.setSourceId(System.currentTimeMillis());
                    dingTalkTodoDTO.setDingNotify(Integer.valueOf(1));
                    dingTalkTodoDTO.setDescription(needUrl);
                    dingTalkTodoDTO.setPriority(40);
                    dingTalkTodoDTO.setSubject("请需求人维护用车申请【" + xhUseVehicleInfo.getProjectName() + "】的耗材明细");
                    dingTalkTodoDTO.setPcUrl(needUrl);
                    dingTalkTodoDTO.setCreateorId(dingdingOaService.getUnionid(dingCreateBy));
                    dingTalkTodoDTO.setExecutorIds(Arrays.asList(dingdingOaService.getUnionid(dingCreateBy)));
                    dingdingOaService.createPlan(dingTalkTodoDTO);
                    //装车人信息
                    dingTalkTodoDTO.setSourceId(System.currentTimeMillis());
                    dingTalkTodoDTO.setPcUrl(loadUrl);
                    dingTalkTodoDTO.setDescription(loadUrl);
                    dingTalkTodoDTO.setSubject("请装车人维护用车申请【" + xhUseVehicleInfo.getProjectName() + "】的耗材明细");
                    dingTalkTodoDTO.setExecutorIds(Arrays.asList(dingdingOaService.getUnionid(staffId)));
                    dingdingOaService.createPlan(dingTalkTodoDTO);
                } catch (Exception e) {
                    log.error(e.getMessage());
                    e.printStackTrace();
                }
                //发送评论，将以上地址填写到评论中
                this.addCommentDetail(xhUseVehicleInfo, needUrl, loadUrl);
            }
        }
    }

    private void addCommentDetail(XhUseVehicleInfo xhUseVehicleInfo, String needUrl, String loadUrl) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("需求人耗材明细："+needUrl);
        stringBuilder.append(System.lineSeparator());
        stringBuilder.append("装车人耗材明细："+loadUrl);
        //保存评论
        XhUseVehicleInfoDetails xhUseVehicleInfoDetails = new XhUseVehicleInfoDetails();
        xhUseVehicleInfoDetails.setCreateTime(DateUtils.getNowDate());
        xhUseVehicleInfoDetails.setInfoId(xhUseVehicleInfo.getId());
        //耗材明细url填充
        xhUseVehicleInfoDetails.setComments(stringBuilder.toString());
        //耗材需求
        xhUseVehicleInfoDetails.setType(XHConstant.STR_3);
        int insert = xhUseVehicleInfoDetailsService.insert(xhUseVehicleInfoDetails);
        if (insert > 0){
            //评论
            try {
                dingdingOaService.addComments(xhUseVehicleInfo.getId());
            } catch (Exception e) {
                log.error("评论耗材明细错误:{}",e);
                e.printStackTrace();
            }
        }
    }

    private void saveOrUpdateRecord(JSONObject msgJsonObject, XhUseVehicleInfo xhUseVehicleInfo, String type, String activityName) {
        //提取任务id
        String taskId = msgJsonObject.getString("taskId");
        if (XHConstant.DING_MSG_FINISH.equals(type)){
            //finish 消息不存储，根据任务id更新
            XhVehicleInfoApplyRecord msgRecord = new XhVehicleInfoApplyRecord();
            BeanMapperUtils.copy(msgJsonObject,msgRecord);
            // 根据taskId 查询任务记录，更新结果
            Optional.ofNullable(xhVehicleInfoApplyRecordService.lambdaQuery().eq(XhVehicleInfoApplyRecord::getTaskId,taskId).last(" limit 1").one()).ifPresent(record->{
                record.setResult(msgRecord.getResult());
                if (msgRecord.getFinishTime() != null) {
                    record.setFinishTime(msgRecord.getFinishTime());
                    record.setFinishTimeDate(XHUtils.timestampToLocalDateTime(msgRecord.getFinishTime()));
                }
                record.setType(msgRecord.getType());
                xhVehicleInfoApplyRecordService.updateById(record);
            });

            //根据损失明细结果校验是否流程结束
            this.checkOrderComplete(xhUseVehicleInfo,type,activityName);
        }else if (XHConstant.DING_MSG_START.equals(type)){
            // start 消息，如果存在重复不保存
            if (xhVehicleInfoApplyRecordService.lambdaQuery()
                    .eq(XhVehicleInfoApplyRecord::getVehicleId,xhUseVehicleInfo.getId())
                    .eq(XhVehicleInfoApplyRecord::getType,type)
                    .eq(XhVehicleInfoApplyRecord::getTaskId,taskId).count() == 0){
                this.saveRecord(msgJsonObject,xhUseVehicleInfo);
            }
        }else if (XHConstant.DING_MSG_COMMENT.equals(type)){
            // comment 消息，跟新activityName
            msgJsonObject.put("activityName","添加评论");
            msgJsonObject.put("bizCategoryId",msgJsonObject.getString("content"));
            this.saveRecord(msgJsonObject,xhUseVehicleInfo);
        }else {
            //cancel 消息进行存储
            this.saveRecord(msgJsonObject,xhUseVehicleInfo);
        }
    }

    @Override
    public XhUseVehicleInfo selectInfoByInstanceId(String instanceId) {
        LambdaQueryWrapper<XhUseVehicleInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(XhUseVehicleInfo::getRemark,instanceId);
        return xhUseVehicleInfoMapper.selectOne(queryWrapper);
    }

    private void saveRecord(JSONObject msgJsonObject, XhUseVehicleInfo xhUseVehicleInfo){
        XhVehicleInfoApplyRecord xhDriverInfoApplyRecord = JSONObject.parseObject(msgJsonObject.toJSONString(), XhVehicleInfoApplyRecord.class);
        xhDriverInfoApplyRecord.setEventType(msgJsonObject.getString("EventType"));
        xhDriverInfoApplyRecord.setVehicleId(xhUseVehicleInfo.getId());
        if (xhDriverInfoApplyRecord.getFinishTime() != null) {
            xhDriverInfoApplyRecord.setFinishTimeDate(XHUtils.timestampToLocalDateTime(xhDriverInfoApplyRecord.getFinishTime()));
        }
        if (xhDriverInfoApplyRecord.getCreateTime() != null){
            xhDriverInfoApplyRecord.setCreateTimeDate(XHUtils.timestampToLocalDateTime(xhDriverInfoApplyRecord.getCreateTime()));
        }
        xhVehicleInfoApplyRecordService.save(xhDriverInfoApplyRecord);
    }

    @Override
    public void checkOrderComplete(XhUseVehicleInfo xhUseVehicleInfo, String type, String activityName) {
        //更新订单状态
        // type: finish activityName:项目经理回执审批
        try{
            if (StringUtils.equals(activityName,sysDictDataService.selectDictLabel(XHConstant.POINT_TYPE, XHConstant.STR_16))){
                //项目经理回执审批：标识最后一个节点，订单完成即可
                XhVehicleOrderInfo orderInfo = xhVehicleOrderInfoService.lambdaQuery().eq(XhVehicleOrderInfo::getVehicleId,xhUseVehicleInfo.getId()).one();
                if (orderInfo != null){
                    orderInfo.setStatus(XHConstant.ORDER_STATUS_COMPLETE);
                    xhVehicleOrderInfoService.updateById(orderInfo);
                }
            }
//            else if (StringUtils.equals(activityName,sysDictDataService.selectDictLabel(XHConstant.POINT_TYPE, XHConstant.STR_15))){
//                //项目经理回执审批，查询损失明细，存在明细标识有损失，查询不到标识没有
//                if (xhVehicleInfoMaterialService.lambdaQuery().eq(XhVehicleInfoMaterial::getVehicleId,xhUseVehicleInfo.getId())
//                        .eq(XhVehicleInfoMaterial::getType,XHConstant.STR_3).count() == 0){
//                    XhVehicleOrderInfo orderInfo = xhVehicleOrderInfoService.lambdaQuery().eq(XhVehicleOrderInfo::getVehicleId,xhUseVehicleInfo.getId()).one();
//                    if (orderInfo != null){
//                        orderInfo.setStatus(XHConstant.ORDER_STATUS_COMPLETE);
//                        xhVehicleOrderInfoService.updateById(orderInfo);
//                    }
//                }
//            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("当前任务处理结束失败："+e.getMessage());
        }
    }
}
